package com.jn.exam.exam.controller;


import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jn.exam.JwtUtils;
import com.jn.exam.R;
import com.jn.exam.UUIDUtil;
import com.jn.exam.exam.entity.*;
import com.jn.exam.exam.service.ExamService;
import com.jn.exam.exam.service.PaperService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 江南大学1033190417
 * @since 2022-02-10
 */
@RestController
@RequestMapping("/exam/exam")
@Api(description = "考试部分")
public class ExamController {

    @Autowired
    private ExamService examService;

    @Autowired
    private PaperService paperService;

    /*
       {
         "exam":{
                "id":
                "paper_id":
                .....
                 },
         "teacherIds1":["","",""],
         "teacherIds2":["","",""]

       }
     */
    @ApiOperation("将试卷发布考试")
    @PostMapping("releasePaperToExam")
    @Transactional
    public R releasePaperToExam(@RequestBody Map<String, Object> param) {
        String jsonString = JSONObject.toJSONString(param.get("exam"));
        Exam exam = JSONObject.parseObject(jsonString, Exam.class);
        exam.setId(UUIDUtil.getUUID()).setGmtCreate(new Date()).setGmtModified(new Date());
        boolean save = examService.saveExam(exam);
        String paperId = exam.getPaperId();
        Paper paper = new Paper();
        paper.setId(paperId).setStatus("7");//试卷已发布考试不可修改
        boolean update = paperService.updateById(paper);
        String examId = exam.getId();
        Map<String, Object> param2 = new HashMap<>();
        param2.put("examId", examId);
        String[] teacherIds1 = Convert.toStrArray(param.get("teacherIds1"));
        String[] teacherIds2 = Convert.toStrArray(param.get("teacherIds2"));
        if (teacherIds1 != null && teacherIds1.length != 0) {
            param2.put("teacherIds", teacherIds1);
            //添加监考老师
            boolean isOK1 = examService.addExamProctor(param2);
            if (!isOK1) {
                return R.error().message("发布失败");
            }
        }
        if (teacherIds2 != null && teacherIds2.length != 0) {
            //添加阅卷老师
            param2.put("teacherIds", teacherIds2);
            boolean isOK2 = examService.addExamMarking(param2);
            if (!isOK2) {
                return R.error().message("发布失败");
            }
        }
        if (save && update) {
            return R.ok().message("发布成功");
        }
        return R.error().message("发布失败");
    }


    @ApiOperation("删除考试")
    @DeleteMapping("deleteExam")
    @Transactional
    public R deleteExam(String examId) {
        boolean isOK = examService.deleteExam(examId);
        if (isOK) {
            return R.ok().message("删除成功");
        }
        return R.error().message("删除失败");
    }

    @ApiOperation("添加监考老师")
    @PutMapping("addProctor")
    public R addProctor(String examId, String teacherId) {
        Map<String, Object> param = new HashMap<>();
        String[] teacherIds = new String[1];
        teacherIds[0] = teacherId;
        param.put("teacherIds", teacherIds);
        param.put("examId", examId);
        boolean b = examService.addExamProctor(param);
        if (b) {
            return R.ok().message("添加成功");
        }
        return R.error().message("老师已在列表");
    }

    @ApiOperation("添加阅卷老师")
    @PutMapping("addMarking")
    public R addMarking(String examId, String teacherId) {
        Map<String, Object> param = new HashMap<>();
        String[] teacherIds = new String[1];
        teacherIds[0] = teacherId;
        param.put("teacherIds", teacherIds);
        param.put("examId", examId);
        try {
            boolean b = examService.addExamMarking(param);
            return R.ok().message("添加成功");

        } catch (Exception e) {
            return R.error().message("老师已在列表");
        }
    }

    @ApiOperation("移除监考老师")
    @DeleteMapping("removeProctor")
    public R removeProctor(String examId, String teacherId) {
        boolean isOK = examService.removeProctor(examId, teacherId);
        if (isOK) {
            return R.ok().message("移除成功");
        }
        return R.error().message("移除失败");
    }

    @ApiOperation("移除阅卷老师")
    @DeleteMapping("removeMarking")
    public R removeMarking(String examId, String teacherId) {
        boolean isOK = examService.removeMarking(examId, teacherId);
        if (isOK) {
            return R.ok().message("移除成功");
        }
        return R.error().message("移除失败");
    }

    @ApiOperation("修改考试信息")
    @PostMapping("updateExam")
    public R updateExam(@RequestBody Exam exam) {
        boolean update = examService.updateById(exam);
        if (update) {
            return R.ok().message("更新成功");
        }
        return R.error().message("更新失败");
    }

    @ApiOperation("查询某考试的监考老师")
    @GetMapping("getProctorTeacher")
    public R getProctorTeacher(String examId) {
        List<Teacher> teachers = examService.getProctorTeacher(examId);
        return R.ok().data("teachers", teachers);
    }

    @ApiOperation("查询某考试的阅卷老师")
    @GetMapping("getMarkingTeacher")
    public R getMarkingTeacher(String examId) {
        List<Teacher> teachers = examService.getMarkingTeacher(examId);
        return R.ok().data("teachers", teachers);
    }

    /**
     * 老师发布的考试
     * 主要为了发布者可以对考试修改
     *
     * @param request 啊哈
     * @return 1  未开始
     * 2  已开始
     * 3  已结束
     */
    @ApiOperation("考试所用试卷的管理者才能查看自己发布的考试")
    @PostMapping("getExam")
    public R getExam(HttpServletRequest request, @RequestBody Exam exam, long current, long limit, int status) {
        String teacherId = JwtUtils.getMemberIdByJwtToken(request);
        List<String> examIds = examService.getExamIds(teacherId);
        return pageExam(exam, current, limit, status, examIds);
    }

    @ApiOperation("查看我的监考")
    @PostMapping("getMyProctor")
    public R getMyProctor(HttpServletRequest request, @RequestBody Exam exam, long current, long limit, int status) {
        String teacherId = JwtUtils.getMemberIdByJwtToken(request);
        //查询我监考的试卷id
        List<String> examIds = examService.getMyProctorExamIds(teacherId);
        return pageExam(exam, current, limit, status, examIds);//分页查询
    }

    @ApiOperation("查询我的阅卷")
    @PostMapping("getMyMarking")
    public R getMyMarking(HttpServletRequest request, @RequestBody Exam exam, long current, long limit, int status) {
        String teacherId = JwtUtils.getMemberIdByJwtToken(request);
        List<String> examIds = examService.getMyMarkingExamIds(teacherId);
        return pageExam(exam, current, limit, status, examIds);
    }


    @ApiOperation("查询所有状态的考试")
    @PostMapping("pageAllStatusExam")
    public R pageAllStatusExam(@RequestBody Exam exam, long current, long limit, int status) {
        return pageExam(exam, current, limit, status, null);
    }


    @ApiOperation("考生报名考试")
    @PostMapping("registerForExam")
    public R registerForExam(HttpServletRequest request, String examId) {
        String studentId = JwtUtils.getMemberIdByJwtToken(request);
        Map<String, Object> param = new HashMap<>();
        param.put("examId", examId);
        param.put("studentId", studentId);
        try {
            boolean isOK = examService.registerForExam(param);
            if (isOK) {
                return R.ok().message("报名成功");
            }
        } catch (Exception e) {
            return R.error().message("已报名");
        }
        return R.error().message("报名失败");
    }

    @ApiOperation("考生放弃考试")
    @DeleteMapping("leaveExam")
    public R leaveExam(HttpServletRequest request, String examId) {
        String studentId = JwtUtils.getMemberIdByJwtToken(request);
        boolean isOK = examService.leaveExam(studentId, examId);
        if (isOK) {
            return R.ok().message("成功");
        }
        return R.error().message("失败");
    }

    @ApiOperation("学生查询与自己相关的考试")
    @PostMapping("getStudentExam")
    public R getStudentExam(HttpServletRequest request, @RequestBody Exam exam, long current, long limit, int status) {
        String studentId = JwtUtils.getMemberIdByJwtToken(request);
        List<String> examIds = examService.getStudentExamIds(studentId);
        return pageExam(exam, current, limit, status, examIds);
    }


    /*
   "success": true,
   "code": 20000,
   "message": "成功",
   "data": {
     "result": [
       {
         "number": 2,
         "attend": -1
       },
       {
         "number": 1,
         "attend": 0
       },
       {
         "number": 1,
         "attend": 1
       }
     ]
   }
 */
    @ApiOperation("拿到某场考试的所有学生的在线情况")
    @GetMapping("getAllStudentAttendStatusOfExam")
    public R getAllStudentAttendStatusOfExam(String examId) {
        List<Map<String, Object>> result = examService.getAllStudentAttendStatusOfExam(examId);
        return R.ok().data("result", result);
    }


    @ApiOperation("试卷管理者移除某学生参加的考试")
    @PostMapping("deleteOneStudentForExam")
    public R deleteOneStudentForExam(String examId, String studentId) {
        boolean b = examService.leaveExam(studentId, examId);
        if (b) {
            return R.ok().message("移除成功");
        }
        return R.error().message("移除失败");
    }

    private R pageExam(Exam exam, long current, long limit, int status, List<String> examIds) {
        QueryWrapper<Exam> wrapper = new QueryWrapper<>();
        String name = exam.getName();
        String remark = exam.getRemark();
        Date startTime = exam.getStartTime();
        Date endTime = exam.getEndTime();
        Date gmtCreate = exam.getGmtCreate();
        Date gmtModified = exam.getGmtModified();
        Date now = new Date();
        if (!StringUtils.isEmpty(name)) {
            wrapper.like("name", name);
        }
        if (!StringUtils.isEmpty(remark)) {
            wrapper.eq("remark", remark);
        }
        if (startTime != null) {
            wrapper.ge("start_time", startTime);
        }
        if (endTime != null) {
            wrapper.le("end_time", endTime);
        }
        if (examIds != null && examIds.size() != 0) {
            wrapper.in("id", examIds);
        }
        if (gmtCreate != null) {
            wrapper.ge("gmt_create", gmtCreate);
        }
        if (gmtModified != null) {
            wrapper.le("gmt_modified", gmtModified);
        }
        if (status == 1) {//未开始
            wrapper.ge("start_time", now);
        } else if (status == 2) {//正在
            wrapper.lt("start_time", now).gt("end_time", now);
        } else {
            assert status == 3;//已结束
            wrapper.le("end_time", now);
        }
        wrapper.orderByDesc("start_time");
        Page<Exam> page = new Page<>();
        page.setCurrent(current).setSize(limit);
        examService.page(page, wrapper);
        List<Exam> exams = page.getRecords();
        long total = page.getTotal();
        return R.ok().data("exams", exams).data("total", total);
    }

}

